package cn.growthgate.fgo.common.base;

import java.io.Serializable;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;

import org.springframework.beans.factory.annotation.Autowired;

import com.baomidou.mybatisplus.mapper.BaseMapper;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;

import cn.growthgate.fgo.util.CollectionUtils;
import cn.growthgate.fgo.util.StringUtils;

public class BaseServiceImpl<M extends BaseMapper<T>, T> extends ServiceImpl<BaseMapper<T>, T>
		implements BaseService<T> {
	
	@Autowired
	protected M baseMapper;

	@Override
	public Page<T> selectPage(Integer current, Integer size, Wrapper<T> wrapper) {
		return selectPage(current, size, null, null, wrapper);
	}

	@Override
	public Page<T> selectPage(Integer current, Integer size, String orderByField, Boolean isAsc, Wrapper<T> wrapper) {
		return selectPage(constPage(current, size, orderByField, isAsc, wrapper, null), wrapper);
	}

	/**
	 * 根据参数构造page以及修改wrapper
	 * @param current
	 * @param size
	 * @param orderByField
	 * @param isAsc
	 * @param wrapper
	 * @param tableAlias 表别名，可为空
	 * @return
	 */
	protected Page<T> constPage(Integer current, Integer size, String orderByField, Boolean isAsc, Wrapper<T> wrapper,
			String tableAlias) {
		Page<T> page = new Page<T>();
		page.setOpenSort(false);
		if (current != null && size != null) {
			page.setCurrent(current);
			page.setSize(size);
		}
		if (StringUtils.isNotBlank(orderByField) && isAsc != null) {
			wrapper.orderBy(orderByField, isAsc);
			// 防止数据项多次出现的bug
			if (StringUtils.isBlank(tableAlias)) {
				wrapper.orderBy("id");
			} else {
				wrapper.orderBy(tableAlias + ".id");
			}
		}
		return page;
	}

	@Override
	public BaseVo<T> transformVo(T entity) {
		return new BaseVo<>();
	}

	@Override
	public List<BaseVo<T>> transformVo(List<T> list) {
		if (list == null) {
			return null;
		}
		return list.stream().map(t -> transformVo(t)).collect(Collectors.toList());
	}

	@Override
	public Page<BaseVo<T>> transformVo(Page<T> page) {
		Page<BaseVo<T>> result = new Page<>();
		result.setTotal(page.getTotal());
		result.setRecords(transformVo(page.getRecords()));
		return result;
	}

	@Override
	public List<T> selectList(String orderByField, Boolean isAsc, Wrapper<T> wrapper) {
		if (StringUtils.isNotBlank(orderByField) && isAsc != null && wrapper != null) {
			wrapper.orderBy(orderByField, isAsc);
		}
		return baseMapper.selectList(wrapper);
	}

	@Override
	public List<T> selectAll() {
		return baseMapper.selectList(null);
	}

	@Override
	public T selectOne(Wrapper<T> wrapper) {
		wrapper.last("LIMIT 1");
		return super.selectOne(wrapper);
	}

	@Override
	public Wrapper<T> newWrapper() {
		return new EntityWrapper<>();
	}

	@Override
	public boolean deleteBatchIds(Collection<? extends Serializable> idList) {
		return CollectionUtils.isNotEmpty(idList) ? super.deleteBatchIds(idList) : true;
	}

	@Override
	public boolean insertBatch(List<T> entityList) {
		return CollectionUtils.isNotEmpty(entityList) ? super.insertBatch(entityList) : true;
	}

}
